package com.flying.invest.strategy.service;

import java.util.Date;

import com.flying.common.annotation.DaoCreate;
import com.flying.common.annotation.DaoQuery;
import com.flying.common.annotation.DaoRemove;
import com.flying.common.annotation.DaoUpdate;
import com.flying.common.annotation.Transaction;
import com.flying.common.util.Codes;
import com.flying.framework.annotation.MethodInfo;
import com.flying.framework.annotation.Param;
import com.flying.framework.annotation.Service;
import com.flying.framework.context.ServiceContext;
import com.flying.framework.exception.AppException;
import com.flying.framework.model.ActionResult;
import com.flying.framework.model.ModelFactory;
import com.flying.framework.model.QueryResult;
import com.flying.framework.service.AbstractService;
import com.flying.invest.invest.TransactionType;
import com.flying.invest.stat.service.WaveStrategyStageStatService;
import com.flying.invest.strategy.model.StrategyGridDetail;
import com.flying.invest.strategy.model.StrategyGridDetailExt;

@Service(value="StrategyGridDetailService", desc="网格策略明细")
public class StrategyGridDetailService extends AbstractService{
	private WaveStrategyStageStatService statServce;
	
	public void setStrategyStageStatService(WaveStrategyStageStatService s) {
		this.statServce = s;
	}
        
	@MethodInfo("新增")
	@DaoCreate(entity=StrategyGridDetail.ENTITY_NAME)
	public StrategyGridDetail create(
			@Param(value=StrategyGridDetail.USER_ID, required=true,	desc="所属用户") Long user_id,
			@Param(value=StrategyGridDetail.TYPE_ID, required=true,	desc="策略类型") Long type_id,
			@Param(value=StrategyGridDetail.INVEST_ID, required=true,	desc="投资项目") Long invest_id,
			@Param(value=StrategyGridDetail.STRATEGY_ID, required=true,	desc="策略ID") Long strategy_id,
			
			@Param(value=StrategyGridDetail.NUM, required=true,	desc="期数") Integer num,
			@Param(value=StrategyGridDetail.GRID_BUY_PRICE, required=false,	desc="网格买入价格") Double grid_buy_price,
			@Param(value=StrategyGridDetail.PRICE_INTERVAL, required=true,	desc="网格间隔比例") Double price_interval,
			@Param(value=StrategyGridDetail.GRID_SELL_PRICE, required=false,	desc="网格卖出价格") Double grid_sell_price,
			@Param(value=StrategyGridDetail.GRID_AMOUNT, required=false,	desc="网格资金") Double grid_amount,
			@Param(value=StrategyGridDetail.GRID_QUANTITY, required=false,	desc="网格数量") Double grid_quantity
		
		) {
		
		return null;
	}
	
	protected StrategyGridDetail create2(StrategyGridDetail d) {
		return this.create(d.getUserId(), d.getTypeId(), d.getInvestId(), d.getStrategyId(), 
				d.getNum(), d.getGridBuyPrice(), d.getPriceInterval(), d.getGridSellPrice(), d.getGridAmount(), d.getGridQuantity());
	}

	@MethodInfo("修改")
	@DaoUpdate(entity=StrategyGridDetail.ENTITY_NAME)
	public ActionResult update(
		
			@Param(value=StrategyGridDetail.DETAIL_ID, required=true,	desc="ID") Long detail_id,
			@Param(value=StrategyGridDetail.USER_ID, required=true,	desc="所属用户") Long user_id,
			@Param(value=StrategyGridDetail.TYPE_ID, required=true,	desc="策略类型") Long type_id,
			@Param(value=StrategyGridDetail.INVEST_ID, required=true,	desc="投资项目") Long invest_id,
			@Param(value=StrategyGridDetail.STRATEGY_ID, required=true,	desc="策略ID") Long strategy_id,
			@Param(value=StrategyGridDetail.NUM, required=true,	desc="期数") Integer num,
			@Param(value=StrategyGridDetail.GRID_BUY_PRICE, required=false,	desc="网格买入价格") Double grid_buy_price,
			@Param(value=StrategyGridDetail.PRICE_INTERVAL, required=true,	desc="网格间隔比例") Double price_interval,
			@Param(value=StrategyGridDetail.GRID_SELL_PRICE, required=false,	desc="网格卖出价格") Double grid_sell_price,
			@Param(value=StrategyGridDetail.GRID_AMOUNT, required=false,	desc="网格资金") Double grid_amount,
			@Param(value=StrategyGridDetail.GRID_QUANTITY, required=false,	desc="网格数量") Double grid_quantity,
			@Param(value=StrategyGridDetail.BUY_PRICE, required=false,	desc="实际买入价格") Double buy_price,
			@Param(value=StrategyGridDetail.BUY_AMOUNT, required=false,	desc="实际买入金额") Double buy_amount,
			@Param(value=StrategyGridDetail.BUY_QUANTITY, required=false,	desc="实际买入数量") Double buy_quantity,
			@Param(value=StrategyGridDetail.SELL_PRICE, required=false,	desc="卖出价格") Double sell_price,
			@Param(value=StrategyGridDetail.SELL_AMOUNT, required=false,	desc="实际卖出金额") Double sell_amount,
			@Param(value=StrategyGridDetail.SELL_QUANTITY, required=false,	desc="实际卖出数量") Double sell_quantity
			
		) {
		
		return null;
	}

	@MethodInfo("修改")
	@DaoUpdate(entity=StrategyGridDetail.ENTITY_NAME)
	protected ActionResult updateByTransaction2(
			@Param(value=StrategyGridDetail.DETAIL_ID, required=true,	desc="ID") Long detail_id,
			@Param(value=StrategyGridDetail.GRID_SELL_PRICE, required=false,	desc="网格卖出价格") Double grid_sell_price,
			
			@Param(value=StrategyGridDetail.BUY_PRICE, required=false,	desc="实际买入价格") Double buy_price,
			@Param(value=StrategyGridDetail.BUY_QUANTITY, required=false,	desc="实际买入数量") Double buy_quantity,
			@Param(value=StrategyGridDetail.BUY_AMOUNT, required=false,	desc="实际买入金额") Double buy_amount,
			@Param(value=StrategyGridDetail.TOTAL_BUY_COUNT, required=false,	desc="总买入笔数") Integer total_buy_count,
			@Param(value=StrategyGridDetail.TOTAL_BUY_AMOUNT, required=false,	desc="总买入金额") Double total_buy_amount,
			
			@Param(value=StrategyGridDetail.SELL_PRICE, required=false,	desc="卖出价格") Double sell_price,
			@Param(value=StrategyGridDetail.SELL_QUANTITY, required=false,	desc="实际卖出数量") Double sell_quantity,
			@Param(value=StrategyGridDetail.SELL_AMOUNT, required=false,	desc="实际卖出金额") Double sell_amount,
			@Param(value=StrategyGridDetail.TOTAL_SELL_COUNT, required=false,	desc="总卖出笔数") Integer total_sell_count,
			@Param(value=StrategyGridDetail.TOTAL_SELL_AMOUNT, required=false,	desc="总卖出金额") Double total_sell_amount
		) {
		
		return null;
	}

	@MethodInfo("修改")
	@Transaction
	public ActionResult updateByTransaction(
			@Param(value=StrategyGridDetail.DETAIL_ID, required=true,	desc="ID") Long detail_id,
			@Param(value=StrategyGridDetail.GRID_SELL_PRICE, required=false,	desc="网格卖出价格") Double grid_sell_price,

			@Param(value="transaction_id", required=true,	desc="ID") Long transaction_id,
			@Param(value="transaction_type", required=true,	desc="交易类型", enumClass=TransactionType.class) Integer transaction_type,
			@Param(value="price", required=true,	desc="交易价格") Double price,
			@Param(value="quantity", required=true,	desc="交易数量") Double quantity,
			@Param(value="amount", required=true,	desc="交易数量") Double amount
		) {
		var d = this.findById(detail_id);
		if(transaction_type == TransactionType.BUY.value()) {
			this.statServce.createForBuy(d.getUserId(), d.getInvestId(), d.getTypeId(), d.getStrategyId(), detail_id, 
					price, amount, quantity, transaction_id, d.getGridSellPrice(), new Date());
			
			Integer total_buy_count = d.getTotalBuyCount() == null?1: d.getTotalBuyCount() + 1;
			Double total_buy_amount = d.getTotalBuyAmount() == null?amount: d.getTotalBuyAmount()+amount;
			return this.updateByTransaction2(detail_id, grid_sell_price,
					price, quantity, amount, total_buy_count, total_buy_amount,
					null, null, null, d.getTotalSellCount(), d.getTotalSellAmount());
		} else {
			var stat = this.statServce.findForSell(d.getStrategyId(), detail_id);
			this.statServce.updateForSell(stat.getStatId(), price, amount, quantity, 
					transaction_id, new Date(), amount - stat.getBuyAmount());
			
			Integer total_sell_count = d.getTotalSellCount() == null?1: d.getTotalSellCount() + 1;
			Double total_sell_amount = d.getTotalSellAmount() == null?amount: d.getTotalSellAmount() + amount;
			return this.updateByTransaction2(detail_id, d.getGridSellPrice(), 	//对卖出交易，全部清空
					null, null, null, d.getTotalBuyCount(), d.getTotalBuyAmount(),
					null, null, null, total_sell_count, total_sell_amount);
		}
	}

	@MethodInfo("删除")
	@Transaction
	public ActionResult removeByStrategyId(
			@Param(value=StrategyGridDetail.STRATEGY_ID, required=true,	desc="策略ID") Long strategy_id
		) {
		var list = this.findByStrategyId(strategy_id).getRows();
		list.stream().forEach(x -> {
			if(x.getBuyAmount() != null || x.getBuyQuantity() != null) {
				throw new AppException("0101","已经存在交易不能更新/删除明细条目");
			}
			this.removeById(x.getDetailId());
		});
		return null;
	}

	@MethodInfo("删除")
	@DaoRemove(entity=StrategyGridDetail.ENTITY_NAME)
	public ActionResult removeById(
			@Param(value=StrategyGridDetail.DETAIL_ID, required=true,	desc="ID") Long detail_id) {
		return null;
	}

	@MethodInfo("搜索")
	@DaoQuery(entity=StrategyGridDetail.ENTITY_NAME, pageable=true, modelClass=StrategyGridDetail.class)
	public QueryResult<StrategyGridDetail> findAll(
			@Param(value=StrategyGridDetail.STRATEGY_ID, required=false,	desc="策略ID") Long strategy_id,
			@Param(value=Codes.PAGE_NUM, 	required=false, desc="分页页号，默认0") int page,
			@Param(value=Codes.PAGE_SIZE, 	required=false, desc="分页大小，默认10") int rows) {
		return null;
	}

	@SuppressWarnings("unchecked")
	@MethodInfo("搜索")
	@DaoQuery(entity=StrategyGridDetail.ENTITY_NAME, pageable=true, modelClass=StrategyGridDetailExt.class, 
		wsql="total_buy_count >= 1",
		osql="order by invest_id desc, strategy_id")
	public QueryResult<StrategyGridDetailExt> findAll2(
			@Param(value=StrategyGridDetail.USER_ID, required=false,	desc="所属用户") Long user_id,
			@Param(value=StrategyGridDetail.INVEST_ID, required=false,	desc="投资项目") Long invest_id,
			@Param(value=StrategyGridDetail.STRATEGY_ID, required=false,	desc="策略ID") Long strategy_id,
			@Param(value=Codes.PAGE_NUM, 	required=false, desc="分页页号，默认0") int page,
			@Param(value=Codes.PAGE_SIZE, 	required=false, desc="分页大小，默认10") int rows) {
		if(user_id == null) {
			var p = ServiceContext.getContext().getPrincipal();
			user_id = Long.parseLong(p.getId());
		}
		return ModelFactory.create(QueryResult.class, StrategyGridDetail.USER_ID, user_id);
	}

	@MethodInfo("搜索")
	@DaoQuery(entity=StrategyGridDetail.ENTITY_NAME, pageable=false, modelClass=StrategyGridDetail.class, osql ="order by num")
	public QueryResult<StrategyGridDetail> findByStrategyId(
			@Param(value=StrategyGridDetail.STRATEGY_ID, required=true,	desc="策略ID") Long strategy_id) {
		return null;
	}

	@MethodInfo("查询")
	@DaoQuery(entity=StrategyGridDetail.ENTITY_NAME, single=true, throwsNotFoundException=true )
	public StrategyGridDetail findById(
			@Param(value=StrategyGridDetail.DETAIL_ID, required=true,	desc="ID") Long detail_id
		) {
		return null;
	}

}